﻿using System;
using System.Messaging;

namespace PSE.Framework.Messaging
{
    /// <summary>
    /// The base class for all msmq objects.
    /// </summary>
    public class Msmq
    {
        #region Attributes
        protected bool _isConnected;
        protected string _path;
        protected string _machineName;
        protected string _queueName;
        protected string _formatName;
        protected object _machineNameObject;
        protected object _queueNameObject = String.Empty;
        protected object _formatNameObject;
        protected long _queueSizeBytes = 0;
        protected int _queuedMessages = 0;
        protected string _lastErrorMessage;
        protected int _lastErrorCode;
        #endregion

        #region Properties

        /// <summary>
        /// Gets or sets the queue's path.
        /// </summary>
        public string Path
        {
            get { return _path; }
            set
            {
                _path = value;

                MsmqPathUtil msmqPathUtil = new MsmqPathUtil();

                _formatName = msmqPathUtil.GetFormatName(_path);
                _machineName = msmqPathUtil.GetMachineName(_path);
                _queueName = msmqPathUtil.GetQueueName(_path, _machineName);

                _formatNameObject = _formatName;
                _machineNameObject = _machineName;
                _queueNameObject = String.Empty; // Se não for Empty dá problema no Init do MSMQManagement

                _isConnected = false;

            }
        }

        /// <summary>
        /// Gets the size in bytes of the queue.
        /// </summary>
        public long QueueSizeBytes
        {
            get { return _queueSizeBytes; }
        }

        /// <summary>
        /// Gets the number of messages in the queue.
        /// </summary>
        public int QueuedMessages
        {
            get { return _queuedMessages; }
        }        

        /// <summary>
        /// Gets a value indicating whether the MsmqReceiver is connected to a queue.
        /// </summary>
        public bool IsConnected
        {
            get { return _isConnected; }
        } 

        /// <summary>
        /// Gets or sets the last error message that has occurred.
        /// </summary>
        public string LastErrorMessage
        {
            get { return _lastErrorMessage; }
            set { _lastErrorMessage = value; }
        }

        /// <summary>
        /// Gets or sets the last error code that has occurred.
        /// </summary>        
        public int LastErrorCode
        {
            get { return _lastErrorCode; }
            set { _lastErrorCode = value; }
        }

        /// <summary>
        /// Gets the machine's name of the queue's path.
        /// </summary>
        public string MachineName
        {
            get { return _machineName; }
        }

        /// <summary>
        /// Gets the queue's name of the queue's path.
        /// </summary>                
        public string QueueName
        {
            get { return _queueName; }
        }

        /// <summary>
        /// Gets the format's name of the queue's path.        
        /// </summary>        
        /// <example>Direct=OS:MachineName\private$\QueueName</example>
        public string FormatName
        {
            get { return _formatName; }
        }
        #endregion

        #region Events
        /// <summary>
        /// Occurs when the PSE.Framework.Messaging.Msmq object encouters a problem.
        /// </summary>
        public event ErrorEventHandler Error;
        /// <summary>
        /// Occurs when the PSE.Framework.Messaging.Msmq object disconnected.
        /// </summary>
        public event EventHandler Disconnected;
        /// <summary>
        /// Occurs when the PSE.Framework.Messaging.Msmq object connected.
        /// </summary>
        public event EventHandler Connected;
        #endregion

        #region Methods
        protected bool QueueExists(string queue)
        {
            MessageQueue[] msmqArray;
            bool ret;

            ret = false;

            try
            {
                msmqArray = MessageQueue.GetPrivateQueuesByMachine(_machineName);

                foreach (MessageQueue msmq in msmqArray)
                {
                    if (queue.ToUpperInvariant() == msmq.QueueName.ToUpperInvariant())
                    {
                        ret = true;
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return ret;
        }

        protected void HandleError(int errorCode, Exception exception)
        {
            if (Error != null)
                Error(this, new ErrorEventArgs(errorCode, exception));
        }

        protected void HandleDisconnection()
        {
            if (IsConnected)
            {
                if (Disconnected != null)
                    Disconnected(this, EventArgs.Empty);
            }
        }

        protected void HandleConnection()
        {
            if (Connected != null)
                Connected(this, EventArgs.Empty);
        }

        #endregion
    }
}
